/* 
 * File:   Module.h
 * Author: Piotrek
 *
 * Created on 24 kwiecień 2010, 22:16
 */

#ifndef _MODULE_H
#define	_MODULE_H

#include "Triangle.h"
#include "RapidModule.h"
#include <vector>
#include "stdafx.h"
#include <ctype.h>
#include "CubedModule.h"

extern double I[3][3];
extern double T0[3];

using namespace RobotCollisionDetection;

/**
 * @brief Moduł robota
 * 
 * Największy element robota stanowiący bryłę sztywną, bez elementów ruchomych.
 */
class Module : public RapidModule {
public:

    /// kat obrotu wzgledem poprzedniego modulu
    float R;
    /// os obrotu wzgledem poprzedniego modulu
    char axis;
    float X;    ///<przesuniecie w kierunku X wzgledem poprzedniego modulu
    float Y;    ///<przesuniecie w kierunku Y wzgledem poprzedniego modulu
    float Z;    ///<przesuniecie w kierunku Z wzgledem poprzedniego modulu
    

	/// proba z zamknieciem modulu w kwadrat
	CubedModule cModule;

    /// trojkaty tworzece modul
    std::vector< Triangle > triangles;

    /**
     * Konstruktor dla obiektu typu Module na podstawie pliku STL.
     *  @param filepath - sciezka do pliku STL
     *  @param x0,y0,z0 - wspolrzedne modulu WZGLEDEM MODULU POPRZEDNIEGO
     *  @param axis - znak char [x|y|z] odpowiadajacy glownej osi obrotu
	 *  @deprecated Rozdzielilismy tworzenie modulu na 2 czynnosci:
	 *  @n 1. tworzenie pustego modulu ze wspolrzednymi
	 *  @n 2. wczytywanie trojkatow
	 *  @n a ten konstruktor byl uzywany pierwotnie i wykonywal 2 rzeczy naraz.
     */    
	Module(char * filepath, float x0, float y0, float z0, char axis);

	/**
	 * Konstruktor tworzacy pusty modul.
     *  @param x0,y0,z0 - wspolrzedne modulu WZGLEDEM MODULU POPRZEDNIEGO
     *  @param axis - znak char [x|y|z] odpowiadajacy glownej osi obrotu
	 */
	Module(float x0, float y0, float z0, char axis);

    /**
     * Konstruktor wczytujacy modul z pliki STL i przyjmujace pozostale parametry zerowe.
	 * Uzywany do tworzenie Submodulow.
     *  @param filepath - sciezka do pliku STL
     */
    Module(char* filepath);


	/**
     * Konstruktor dla obiektu typu Module tworzacy prostopadloscian o zadanym polozeniu i rozmiarze.     
     *	@param X, Y, Z - wspolrzedne polozenia modulu
     *	@param A, B, C - rozmiar modulu
	 *	@param direction kierunek normalnej (1 -na zewnatrz, -1 -do srodka)
	 */
	Module(float X, float Y, float Z, float A, float B, float C, int direction);

    /**
     * @brief
     * Przepisanie trojkatow z modułu module do modułu wywołującego funkcje.
     *
     * @param module - wskaznik do modulu z trojkatami do przepisania
     */
    void addTriangles(Module * module);

    /**
     * @brief Odczyt trojkatow z pliku STL ASCII
     * 
     * Trojkaty zostana dopisane do modulu, ktory wywowal funkcje.
     * 
     * @param filepath sciezka do pliku
     */
    int readTrianglesFromStl(char * filepath);

    /// rysowanie modulu w srodowisku OpenGL
    void drawModule();
    
	/**
	* Funkcja tworzaca obudowe modulu z prostopadloscianow
	*
	*/
	void createCubedModule();

	/**
	* Funkcja rysujaca przeźroczysty modul zbudowany z prostopadloscianu
	*/
	void drawCubedModule();

    /**
     * @brief
     * Uniwersalna funkcja dokonujaca transformarcji (translacja + rotacja) modulu.
     *
     * Transformacja dokonywana jest na zasadzie skladania obrotow. Podstawy teoretyczne: http://www.robotyka.com/teoria.php/teoria.43.
     * Nowe polozenie jest wyliczane na podstawie wzoru:
     * @n [x,y,z]' = [Tprev]*[T]*[x0,y0,z0]', gdzie Tprev,T-macierze, x,y,z - wspolrzedne
     *
     * Funkcja jest zoptymalizowana do wykonywania rotacji tylko wzgledem jednej osi jednoczenie.
     *
     * @param X, Y, Z   wspolrzedne translacji
     * @param axis  oś rotacji, znak char [x|y|z] lub wartosc 0
     * @param R     kąt rotacji, w stopniach
     * @param Rprev   macierz rotacji poprzedniego modulu lub macierz jednostkowa I
	 * @param Tprev   wektor translacji poprzedniego modulu lub wektor zerowy
     * @param whichTriangles   0 -aktualizacja trojkatow zerowych, !0 aktualizacja trojkotow rzeczywistych zobacz @ref Triangle
     */
    void transform(float X, float Y, float Z, float axis, float R, double Rprev[3][3], double Tprev[3], int whichTriangles);

    /**
     * Transformacja na podstawie macierzy transformacji T wzgledem poprzedniego modulu.
     * @n Za parametry X,Y,Z,axis,R - brane sa odpowiadajace im parametry modulu.
     * @n forceUpdate = 0
     * @param Rprev   macierz rotacji poprzedniego modulu lub macierz jednostkowa I
	 * @param Tprev   wektor translacji poprzedniego modulu lub wektor zerowy
     */
    void transform(double Rprev[3][3], double Tprev[3]);

};

#endif	/* _MODULE_H */

